import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.util.List;


public class broker implements QueryInterface {
	private ConfigurationManager propertymanager;
	private static Logger log = Logger.getLogger();
	private TripleDb tripleDb;
	
	
	private void init() throws IOException
	{
		propertymanager = ConfigurationManager.getPropertyManager();
		tripleDb = TripleDb.getTripleDb();
	}
	
	
	public String query(String id, String mainkey, String subkey)
			throws RemoteException {
		log.info("Query Called : "+id + " "+ mainkey + " " + subkey);
		if((mainkey == null)||(subkey == null)||(id == null))
			return "0x003";
		
		if((mainkey.length() >= 32) || (subkey.length() >= 32) || (id.length() >= 32))
			return "0x003";
		
		List<String> result = tripleDb.query(mainkey, subkey);
		
		String response = "QUERY-REPLY " + id + " "+ result.size()+"\n";
		
		int i = 1;
		for(String str: result)
		{
			response+="RESPONSE " + id + " " + i++ + " " + str+"\n";
		}
		
		
		return response;
	}
	
	
	public String getBindName() throws IOException
	{
		return propertymanager.getBindName();
	}
	/*Usage java server [port] */
	public static void main(String args[]) {
		
		broker server = new broker();
		
		try{
			server.init();
			QueryInterface serverstub = (QueryInterface) UnicastRemoteObject.exportObject(server, 0);
			
			Registry registry;
			/*Bind to the register.*/
			if(args.length > 1)
				{
					Integer port = Integer.parseInt(args[0]);
					registry = LocateRegistry.getRegistry(port);
				}
			else 
				registry = LocateRegistry.getRegistry();
			
			registry.bind(server.getBindName(), serverstub);
			
			/* Get the registry server ready.
			 * This will handle all incoming socket register/remove/query requests.
			 */
			RegistryServer regServer = new RegistryServer();
			regServer.start();
			
			log.info("Server Ready. Type exit at the command prompt to quit.");
			BufferedReader reader = new BufferedReader( new InputStreamReader(System.in));
			
			while(true)
			{
				String strin = reader.readLine();
				if(strin.equalsIgnoreCase("END") || strin.equalsIgnoreCase("BYE")
					||strin.equalsIgnoreCase("EXIT"))
				    {
					log.info("Unbinding Server ..");
					registry.unbind(server.getBindName());
					log.info("Saving DB ..");
					TripleDb.getTripleDb().saveDB();
					System.exit(0) ;
				    }
			}
			
			
		}catch(Exception ex)
		{
			log.error("Exception !! -- " + ex.getMessage());
			ex.printStackTrace();
		}
		
	}
	
}
